package cn.webrx;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class Util {
    private static String db = "db.dat";
    private static String dblog = "db.log";
    private static Scanner sc = new Scanner(System.in);

    private static List<Room> rooms = new ArrayList<>(50);
    private static List<RoomLog> roomlogs = new ArrayList<>(100);

    /* 初始化房间信息 */
    static {
        File f = new File(db);
        if (f.exists()) {
            rooms = load();
        } else {
            Random rand = new Random();
            for (int i = 10; i < 60; i++) {
                Room room = new Room();
                room.setNo(i);
                room.setNum(rand.nextInt(1, 6));
                room.setPrice(100 * room.getNum());
                room.setEnter(null);
                room.setState(false);
                rooms.add(room);
            }
            save(rooms);
        }

        /*初始化日志*/
        File log = new File(dblog);
        if (log.exists()) {
            roomlogs = loadLog();
        } else {
            List<RoomLog> roomlogs = new ArrayList<>();
            saveLog(roomlogs);
        }
    }

    public static List<Room> load() {
        List<Room> rs = new ArrayList<>();
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(db))) {
            rs = (List<Room>) ois.readObject();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return rs;
    }

    public static void save(List<Room> rooms) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(db))) {
            oos.writeObject(rooms);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void saveLog(List<RoomLog> roomlogs) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(dblog))) {
            oos.writeObject(roomlogs);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static List<RoomLog> loadLog() {
        List<RoomLog> rs = new ArrayList<>();
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(dblog))) {
            rs = (List<RoomLog>) ois.readObject();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return rs;
    }


    public static String input(String msg) {
        sc = new Scanner(System.in);
        System.out.print(msg);
        return sc.nextLine();
    }

    public static String inputNull(String msg) {
        sc = new Scanner(System.in);
        System.out.print(msg);
        return sc.nextLine();
    }

    public static int inputNum(String msg) {
        sc = new Scanner(System.in);
        System.out.print(msg);
        return sc.nextInt();
    }

    public static double inputMoney(String msg) {
        sc = new Scanner(System.in);
        System.out.print(msg);
        return sc.nextDouble();
    }

    public static void menu() {
        while (true) {
            System.out.println();
            System.out.println(center("《宾馆管理系统》", 50, "*"));
            System.out.println(center("1.开房", 50, " "));
            System.out.println(center("2.退房", 50, " "));
            System.out.println(center("3.查询", 50, " "));
            System.out.println(center("4.日志", 50, " "));
            System.out.println(center("0.退出", 50, " "));
            System.out.println("\n");


            String choose = input("请选择功能：");
            switch (choose) {
                case "1":
                    open();
                    break;

                case "2":
                    exit();
                    break;

                case "3":
                    search();
                    break;

                case "4":
                    logs();
                    break;

                default:
                    save(rooms);
                    saveLog(roomlogs);
                    System.out.println();
                    System.out.println("程序退出....");
                    System.out.println();
                    System.exit(1);
                    break;
            }
        }

    }

    public static void logs() {
        Collections.sort(roomlogs, (a, b) -> b.getRoom().getEnter().compareTo(a.getRoom().getEnter()));
        for (RoomLog roomlog : roomlogs) {
            System.out.println("[" + roomlog.getRoom().getNo() + "]" + roomlog.getMsg() + ":" + roomlog.getRoom().getInfo());
        }

        System.out.println();
        System.out.println("查看日志结束");
    }

    public static void exit() {
        System.out.println(center("退房", 38, "-"));
        String c = input("请输入的房间号：");
        Room ok = null;
        for (Room r : rooms) {
            if (r.getNo() == Integer.parseInt(c)) {
                ok = r;
                break;
            }
        }
        if (ok == null) {
            System.err.println("没有此房间号，开房失败，请重新操作。");
        } else {
            ok.setState(false);
            System.out.printf("房间信息：%s%n", ok.getNo() + "号房间（" + ok.getNum() + "人间）一天费用:" + ok.getPrice() + "元。");
            System.out.printf("入住时间：%tF %<tT%n", ok.getEnter());
            System.out.printf("入住押金：%f%n", ok.getUser().getMoney());
            System.out.printf("退房时间：%tF %<tT%n", new Date());
            System.out.printf("入住：天，费用：元%n", getDays(ok.getEnter(), new Date()), getDays(ok.getEnter(), new Date()) * ok.getPrice());

            //此处有问题，退的是二天的 入住一天的费用
            System.out.printf("退换押金：%f元", ok.getUser().getMoney() - getDays(ok.getEnter(), new Date()) * ok.getPrice());


            loadLog();
            RoomLog roomlog = new RoomLog();
            roomlog.setRoom(ok);
            roomlog.setMsg("退房");
            roomlogs.add(roomlog);
            saveLog(roomlogs);
            save(rooms);
            System.out.println();
            System.out.println("谢谢惠顾");
        }
    }


    /**
     * Description: 实现开房
     *
     * @date: 2022/9/23 17:09
     * @params: []
     * @return: void
     */
    public static void open() {
        System.out.println(center("新客户开房", 38, "-"));
        String c = input("请输入的房间号：");
        Room ok = null;
        for (Room r : rooms) {
            if (r.getNo() == Integer.parseInt(c)) {
                ok = r;
                break;
            }
        }
        if (ok == null) {
            System.err.println("没有此房间号，开房失败，请重新操作。");
        } else {
            if (ok.isState()) {
                System.err.println("此房间号已经有人入住，开房失败，请重新操作。");
            } else {
                String id = input("请输入你的身份证号：");
                String name = input("请输入姓名：");
                String tel = input("请输入联系电话：");
                double money = inputMoney(String.format("请输入金额（%d房间，三天押金：%.2f元）", ok.getNum(), ok.getPrice() * 3));
                ok.setState(true);
                ok.setInfo(String.format("欢迎：%s入门宾馆，%s房间,联系电话：%s，开房时间：%tF %<tT", name, c, tel, System.currentTimeMillis()));

                /*保存用户日志信息*/
                User user = new User(id, name, tel, money);
                ok.setUser(user);
                ok.setEnter(new Date());
                RoomLog roomlog = new RoomLog();
                roomlog.setRoom(ok);
                roomlog.setMsg("开房");
                roomlogs.add(roomlog);
                saveLog(roomlogs);


                System.out.println();
                System.out.println("开房成功，你的房间号" + c);
                save(rooms);
            }
        }

    }


    public static String center(String str, int len, String c) {
        int size = (len - str.length()) / 2;
        return c.repeat(size).concat(" " + str + " ").concat(c.repeat(size));
    }

    public static void out(String str) {
        System.out.printf("\033[41m%s\033[0m", str);
    }

    public static void search() {
        while (true) {
            System.out.println(center("查询功能", 38, "-"));

            String c = inputNull("查询房间（请输入房间号或直接回车,输入0返回上一级）：");

            if ("".equalsIgnoreCase(c)) {
                int index = 0;
                for (Room r : rooms) {
                    if (index++ % 10 == 0) {
                        System.out.println();
                    }
                    if (r.isState()) {
                        out(r.toString());
                        System.out.print("\t");
                    } else {
                        System.out.print(r + "\t");
                    }

                }
                System.out.println();
                System.out.println();
            } else if ("0".equalsIgnoreCase(c)) {
                break;
            } else {
                System.out.println("查询房间：" + c);
                int index = 0;

                Room ok = null;
                for (Room r : rooms) {
                    if (r.getNo() == Integer.parseInt(c)) {
                        ok = r;
                        break;
                    }
                }
                if (ok == null) {
                    System.out.println("没有此房间号");
                } else {
                    System.out.print(ok + "\t");
                }
                System.out.println();
                System.out.println();
            }
        }
    }

    public static int getDays(Date start, Date end) {
        return (int) (end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24);
    }
}
